package com.lfs.controller;

import com.lfs.annotations.ParameterValid;
import com.lfs.aspects.Parameter;
import com.lfs.base.dto.Result;
import com.lfs.base.dto.ResultObject;
import com.lfs.base.enums.ErrorCodeEnum;
import com.lfs.base.exception.BusinessException;
import com.lfs.base.util.MD5NewUtils;
import com.lfs.common.cache.redis.base.MapCache;
import com.lfs.common.constant.CommonConstants;
import com.lfs.common.constant.Constant;
import com.lfs.common.utils.StringUtils;
import com.lfs.interfaces.agent.service.AgentSerivce;
import com.lfs.interfaces.dto.ResultReturn;
import com.lfs.interfaces.model.dto.ChargeDto;
import com.lfs.interfaces.model.vo.AgentVo;
import com.lfs.interfaces.model.vo.ChargeVo;
import com.lfs.interfaces.model.vo.OrderInfoVO;
import com.lfs.interfaces.order.service.OrderBaseService;
import com.lfs.service.ApiChargeSerivce;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/charge")
public class ChargeController {

    private Logger logger = LoggerFactory.getLogger(ChargeController.class);

    @Resource
    private ApiChargeSerivce chargeSerivce;

    @Resource
    private OrderBaseService orderBaseService;

    @Value("${bc.clientIps}")
    private String clientIps;

    @Value("${bc.secretKey}")
    private String secretKey;

    @Resource
    private AgentSerivce agentSerivce;

    @Resource
    private MapCache mapCache;

    /**
     * 创建支付请求接口
     * @param chargeDto
     * @return
     * @throws Exception
     */
    @PostMapping("/createWebCharge")
    public ResultReturn<?> createWebCharge(@RequestBody ChargeDto chargeDto) {
        ResultReturn<ChargeVo> resp = new ResultReturn();
        ChargeVo chargeVO = new ChargeVo();
        chargeVO.setReqStreamId(chargeDto.getReqStreamId());
        String payUrl = null;
        if(null == chargeDto){
            throw  new BusinessException("请求的支付参数不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getReqStreamId())){
            throw  new BusinessException("请求的商户订单号不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getChargeType())){
            throw  new BusinessException("请求的支付类型不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getAgtPhone())){
            throw  new BusinessException("请求的商户账号不能为空!");
        }
        try {
//            if (!ValidIp(chargeDto)) {
//                resp.setStatus(CommonConstants.RESP_NOT_IP).setMsg("ip不合法").setData(chargeVO);
//                return resp;
//            }
            long start = System.currentTimeMillis();
            if( null != chargeDto.getChargeMoney()){
                resp = chargeSerivce.charge(chargeDto);
            }else{
                if(CommonConstants.BANK_CARD_TYPE.equals(chargeDto.getChargeType())){
                    List<AgentVo> agents =(List<AgentVo>)mapCache.hget(Constant.HASH_AGENT_INFO_LIST+chargeDto.getAgtPhone(),Constant.HASH_AGENT_INFO_LIST);
                    // 2.redis不存在
                    if (com.lfs.base.util.CollectionUtils.isEmpty(agents)) {
                        // 从数据库获取
                        agents = agentSerivce.getAgentInfoByPhone(chargeDto.getAgtPhone()).getData();
                        // 存入数据库
                        mapCache.hset(Constant.HASH_AGENT_INFO_LIST+chargeDto.getAgtPhone(), Constant.HASH_AGENT_INFO_LIST, agents);
                    }

                    if (CollectionUtils.isNotEmpty(agents)) {
                        AgentVo agent = agents.get(0);
                        if(null != agent && StringUtils.isNotBlank(agent.getAgtOfficeAddr())){
                            payUrl = agent.getAgtOfficeAddr();
                        }
                    }
                    chargeVO.setPayUrl(payUrl.concat("?reqStreamId="+chargeDto.getReqStreamId()+
                            "&chargeMoney="+chargeDto.getChargeMoney()+"&agtPhone="+chargeDto.getAgtPhone())+
                            "&notifyUrl="+chargeDto.getNotifyUrl());
                }
                chargeVO.setAgtPhone(chargeDto.getAgtPhone());
                chargeVO.setApplyTime(Constant.getDateTime());
                resp.setStatus(CommonConstants.RESP_CHARGE_HANDLE).setData(chargeVO)
                        .setMsg("充值提交成功");
            }
            logger.info("-----------总耗时为-----------" + (System.currentTimeMillis() - start));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            resp.setStatus(CommonConstants.RESP_CHARGE_EXCETION).setMsg("提交参数有误").setData(chargeVO);
        }
        logger.info("api充值响应客户端=[reqStreamId=" + resp.getData().getReqStreamId() + "&status=" + resp.getStatus() + "&msg="
                + resp.getMsg() + "]");
        return resp;
    }

    /**
     * 创建laien支付请求接口
     * @param chargeDto
     * @return
     * @throws Exception
     */
    @PostMapping("/createNewCharge")
    public ResultReturn<?> createNewCharge(@RequestBody ChargeDto chargeDto) {
        ResultReturn<ChargeVo> resp = new ResultReturn();
        ChargeVo chargeVO = new ChargeVo();
        chargeVO.setReqStreamId(chargeDto.getReqStreamId());
        String payUrl = null;
        if(null == chargeDto){
            throw  new BusinessException("请求的支付参数不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getReqStreamId())){
            throw  new BusinessException("请求的商户订单号不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getChargeType())){
            throw  new BusinessException("请求的支付类型不能为空!");
        }
        if(StringUtils.isBlank(chargeDto.getAgtPhone())){
            throw  new BusinessException("请求的商户账号不能为空!");
        }
        if(null == chargeDto.getChargeMoney()){
            throw  new BusinessException("请求的充值金额不能为空!");
        }
        try {
//            if (!ValidIp(chargeDto)) {
//                resp.setStatus(CommonConstants.RESP_NOT_IP).setMsg("ip不合法").setData(chargeVO);
//                return resp;
//            }
            long start = System.currentTimeMillis();
            List<AgentVo> agents =(List<AgentVo>)mapCache.hget(Constant.HASH_AGENT_INFO_LIST+chargeDto.getAgtPhone(),Constant.HASH_AGENT_INFO_LIST);
            // 2.redis不存在
            if (com.lfs.base.util.CollectionUtils.isEmpty(agents)) {
                // 从数据库获取
                agents = agentSerivce.getAgentInfoByPhone(chargeDto.getAgtPhone()).getData();
                // 存入数据库
                mapCache.hset(Constant.HASH_AGENT_INFO_LIST+chargeDto.getAgtPhone(), Constant.HASH_AGENT_INFO_LIST, agents);
            }

            if (CollectionUtils.isNotEmpty(agents)) {
                AgentVo agent = agents.get(0);
                if(null != agent && StringUtils.isNotBlank(agent.getAgtOfficeAddr())){
                    payUrl = agent.getAgtOfficeAddr();
                }
            }
            chargeVO.setPayUrl(payUrl.concat("?reqStreamId="+chargeDto.getReqStreamId()+
                    "&chargeMoney="+chargeDto.getChargeMoney()+"&agtPhone="+chargeDto.getAgtPhone())+
                    "&notifyUrl="+chargeDto.getNotifyUrl());
            chargeVO.setAgtPhone(chargeDto.getAgtPhone());
            chargeVO.setBalance(chargeDto.getChargeMoney());
            chargeVO.setApplyTime(Constant.getDateTime());
            resp.setStatus(CommonConstants.RESP_CHARGE_HANDLE).setData(chargeVO)
                    .setMsg("充值提交成功");
            logger.info("-----------总耗时为-----------" + (System.currentTimeMillis() - start));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            resp.setStatus(CommonConstants.RESP_CHARGE_EXCETION).setMsg("提交参数有误").setData(chargeVO);
        }
        logger.info("api充值响应客户端=[reqStreamId=" + resp.getData().getReqStreamId() + "&status=" + resp.getStatus() + "&msg="
                + resp.getMsg() + "]");
        return resp;
    }




    /**
     * 创建支付请求接口
     * @param parameter
     * @return
     * @throws Exception
     */
    @PostMapping("/createCharge")
    @ParameterValid
    public ResultReturn<?> createCharge(@RequestBody Parameter parameter) {
        ResultReturn<ChargeVo> resp = new ResultReturn();
        ChargeVo chargeVO = new ChargeVo();
        chargeVO.setApplyTime(Constant.getDateTime());

        try {
//            if (!ValidIp(chargeDto)) {
//                resp.setStatus(CommonConstants.RESP_NOT_IP).setMsg("ip不合法").setData(chargeVO);
//                return resp;
//            }
            ChargeDto chargeDto = parameter.getObject(ChargeDto.class);
            if(StringUtils.isBlank(chargeDto.getExp())){
                chargeDto.setExp("Web");
            }

            if(null == chargeDto){
                throw  new BusinessException("请求的支付参数不能为空!");
            }
            if(StringUtils.isBlank(chargeDto.getReqStreamId())){
                throw  new BusinessException("请求的商户订单号不能为空!");
            }
            if(StringUtils.isBlank(chargeDto.getChargeType())){
                throw  new BusinessException("请求的支付类型不能为空!");
            }
            if(StringUtils.isBlank(chargeDto.getAgtPhone())){
                throw  new BusinessException("请求的商户账号不能为空!");
            }
            if(null == chargeDto.getChargeMoney()){
                throw  new BusinessException("请求的充值金额不能为空!");
            }
            long start = System.currentTimeMillis();
            resp = chargeSerivce.charge(chargeDto);
            logger.info("-----------总耗时为-----------" + (System.currentTimeMillis() - start));
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            resp.setStatus(CommonConstants.RESP_CHARGE_EXCETION).setMsg("提交参数有误").setData(chargeVO);
        }
        logger.info("api充值响应客户端=[reqStreamId=" + resp.getData().getReqStreamId() + "&status=" + resp.getStatus() + "&msg="
                + resp.getMsg() + "]");
        return resp;
    }

    @PostMapping("/getOrderInfoByOrderNo")
    public Result<?> getOrderInfoByOrderNo(@RequestBody OrderInfoVO orderInfoVO) {
        if(null == orderInfoVO){
            throw new BusinessException("请求查询的参数为空!");
        }
        if(StringUtils.isBlank(orderInfoVO.getOrderNo()) && StringUtils.isBlank(orderInfoVO.getReqStreamId())){
            throw new BusinessException("请求查询的订单号不能为空!");
        }
        if(orderInfoVO.getOrderNo().length() > 19){
            try {
                String orderNo = MD5NewUtils.decrypt(orderInfoVO.getOrderNo(),secretKey);
                orderInfoVO.setOrderNo(orderNo);
            } catch (Exception e) {
                logger.error("获取加密订单号失败:{}!",e.getMessage());
                throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR.getMsg());
            }
        }
        logger.info("根据{}查询订单请求参数",orderInfoVO.toString());
        Map<String,String> resultMap = orderBaseService.getOrderInfoByOrderNo(orderInfoVO);
        if(resultMap.isEmpty()){
            throw new BusinessException("根据订单号未查询到订单记录!");
        }
        return ResultObject.successObject(resultMap, "查询成功");
    }

    @PostMapping("/updateOrderInfo")
    public Result<?> updateOrderInfo(@RequestBody OrderInfoVO orderInfoVO){
        if(null == orderInfoVO){
            throw new BusinessException("请求查询的参数为空!");
        }
        if(StringUtils.isBlank(orderInfoVO.getOrderNo())){
            throw new BusinessException("请求更新的订单号不能为空!");
        }
        try {
            String orderNo = MD5NewUtils.decrypt(orderInfoVO.getOrderNo(),secretKey);
            orderInfoVO.setOrderNo(orderNo);
        } catch (Exception e) {
            logger.error("获取加密订单号失败:{}!",e.getMessage());
            throw new BusinessException(ErrorCodeEnum.PARAMS_ERROR.getMsg());
        }
        logger.info("根据{}修改订单请求参数",orderInfoVO.toString());
        int result = orderBaseService.updateOrderInfo(orderInfoVO);
        if(result <= 0){
            logger.info("提交修改订单信息失败!");
        }
        return ResultObject.successMessage("提交订单信息成功");
    }

    private boolean ValidIp(ChargeDto dto) {

        boolean flag = false;
        String clientIp = dto.getAccountIp();
        logger.info("客户提交的ip：" + clientIp);
        logger.info("客户配置的ip：" + clientIps);
        if (StringUtils.isEmpty(clientIps)) {
            logger.info("客户未配置请求ip白名单,请求失败!");
            return flag;
        } else {
            String[] configarr = clientIps.split(",");
            for (String serviceIp : configarr) {
                if (clientIp.equals(serviceIp)) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }
}
